home *** CD-ROM | disk | FTP | other *** search
- /* fall.c */
-
- /* Animates falling boulders and moving */
- /* arrows. */
-
-
-
- #include "wand_head.h"
- //#include <allegro.h>
- #include "samples.h"
-
- extern char lscreen[NOOFROWS][ROWLEN+1];
- extern int pause1;
- extern int recording;
- extern int audio_flag;
-
- int moving = 0; /* so that bombs explode only if something *hits* them */
-
- int check(mx, my, x, y, dx, dy, sx, sy, howdead)
- /* check for any falling caused by something moving out of x,y along
- vector dx,dy. All the others are constant and should really have
- been global... */
- int x, y, sx, sy, dx, dy, *mx, *my;
- char howdead[25];
- {
- int ret = 0;
- /* if(recording != 2) flushinp(); type ahead gets in the way */
- ret += fall(mx,my,x,y,sx,sy,howdead);
- ret += fall(mx,my,x-dx,y-dy,sx,sy,howdead);
- ret += fall(mx,my,x-dy,y-dx,sx,sy,howdead);
- ret += fall(mx,my,x+dy,y+dx,sx,sy,howdead);
- ret += fall(mx,my,x-dx-dy,y-dy-dx,sx,sy,howdead);
- ret += fall(mx,my,x-dx+dy,y-dy+dx,sx,sy,howdead);
- return ret;
- }
-
- int fall(mx, my, x, y, sx, sy, howdead)
- /* recursive function for falling */
- /* boulders and arrows */
- int x, y, sx, sy, *mx, *my;
- char howdead[25];
- {
- int nx = x, nxu = x, nyl = y, nyr = y, ny = y, retval = 0;
- if ((y > (NOOFROWS-1)) || (y < 0) || (x < 0) || (x > (ROWLEN-1)))
- return(0);
- if (lscreen[y][x] == '~') {
- if (lscreen[y-1][x] == ' ') fall(mx,my,x,y-1,sx,sy,howdead);
- if (lscreen[y+1][x] == ' ') fall(mx,my,x,y+1,sx,sy,howdead);
- if (lscreen[y][x-1] == ' ') fall(mx,my,x-1,y,sx,sy,howdead);
- if (lscreen[y][x+1] == ' ') fall(mx,my,x+1,y,sx,sy,howdead);
- }
- if ((lscreen[y][x] != 'O') && (lscreen[y][x] != ' ') &&
- (lscreen[y][x] != 'M') && (lscreen[y][x] !='\\') &&
- (lscreen[y][x] != '/') && (lscreen[y][x] != '@') &&
- (lscreen[y][x] != '^') && (lscreen[y][x] != 'B'))
- return(0);
- if ((lscreen[y][x] == 'B') && (moving == 0))
- return 0;
- if (lscreen[y][x] == 'O') {
- if ((lscreen[y][x-1] == ' ') && (lscreen[y-1][x-1] == ' '))
- nx--;
- else {
- if ((lscreen[y][x+1] == ' ') && (lscreen[y-1][x+1] == ' '))
- nx++;
- else
- nx = -1;
- }
- if ((lscreen[y][x-1] == ' ') && (lscreen[y+1][x-1] == ' '))
- nxu--;
- else {
- if ((lscreen[y][x+1] == ' ') && (lscreen[y+1][x+1] == ' '))
- nxu++;
- else
- nxu = -1;
- }
- if ((lscreen[y-1][x] == ' ') && (lscreen[y-1][x+1] == ' '))
- nyr--;
- else {
- if ((lscreen[y+1][x] == ' ') && (lscreen[y+1][x+1] == ' '))
- nyr++;
- else
- nyr = -1;
- }
- if ((lscreen[y-1][x] == ' ') && (lscreen[y-1][x-1] == ' '))
- nyl--;
- else {
- if ((lscreen[y+1][x] == ' ') && (lscreen[y+1][x-1] == ' '))
- nyl++;
- else
- nyl = -1;
- }
- }
- if (lscreen[y][x] == '\\') {
- if (lscreen[y-1][++nx] != ' ')
- nx = -1;
- if (lscreen[y+1][--nxu] != ' ')
- nxu = -1;
- if (lscreen[--nyr][x+1] != ' ')
- nyr = -1;
- if (lscreen[++nyl][x-1] != ' ')
- nyl = -1;
- }
- if (lscreen[y][x] == '/') {
- if (lscreen[y-1][--nx] != ' ')
- nx = -1;
- if (lscreen[y+1][++nxu] != ' ')
- nxu = -1;
- if (lscreen[++nyr][x+1] != ' ')
- nyr = -1;
- if (lscreen[--nyl][x-1] != ' ')
- nyl = -1;
- }
- if ((lscreen[y][nx] != ' ') && (lscreen[y][nx] != 'M') &&
- (lscreen[y][nx] != 'B'))
- nx = -1;
- if ((lscreen[y-1][x] == 'O') && (nx >= 0) && (y > 0)) { /* boulder falls ? */
- moving = 1;
- lscreen[y-1][x] = ' ';
- if (lscreen[y][nx] == '@') {
- strcpy(howdead,"a falling boulder");
- if(audio_flag) play_audio_sample(KILLED_BY_O_SND);
- retval = 1;
- }
- if (lscreen[y][nx] == 'M') {
- *mx = *my = -2;
- lscreen[y][nx] = ' ';
- if(audio_flag) play_audio_sample(DEAD_M_SND);
- }
- if (lscreen[y][nx] == 'B') {
- retval = bang(nx,y,mx,my,sx,sy,howdead);
- return retval;
- }
- lscreen[y][nx] = 'O';
-
- draw_object(y-1,x,' ');
- draw_object(y,nx,'O');
- if(audio_flag) play_audio_sample(MOVING_BOULDER_SND);
- refresh_screen();
- delay(pause1);
- retval += fall(mx,my,nx ,y+1,sx,sy,howdead);
- moving = 0;
- retval += check(mx,my,x,y-1,0,1,sx,sy,howdead);
- if (y + 1 < NOOFROWS && lscreen[y+1][nx] == '@') {
- strcpy(howdead,"a falling boulder");
- if(audio_flag) play_audio_sample(KILLED_BY_O_SND);
- return(1);
- }
- if (y + 1 < NOOFROWS && lscreen[y+1][nx] == 'M') {
- *mx = *my = -2;
- lscreen[y+1][nx] = ' ';
- if(audio_flag) play_audio_sample(DEAD_M_SND);
- }
- }
- if ((lscreen[nyr][x] != '^') && (lscreen[nyr][x] != ' ') &&
- (lscreen[nyr][x] != 'M') && (lscreen[nyr][x] != 'B'))
- nyr = -1;
- if ((lscreen[y][x+1] == '<') &&
- (nyr>=0)&&(x+1<ROWLEN)) { /* arrow moves ( < ) ? */
- moving = 1;
- lscreen[y][x+1] = ' ';
- if (lscreen[nyr][x] == '@') {
- strcpy(howdead,"a speeding arrow");
- if(audio_flag) play_audio_sample(KILLED_BY_A_SND);
- retval = 1;
- }
- if (lscreen[nyr][x] == 'M') {
- *mx = *my = -2;
- lscreen[nyr][x] = ' ';
- if(audio_flag) play_audio_sample(DEAD_M_SND);
- }
- if (lscreen[nyr][x] == 'B') {
- retval = bang(x,nyr,mx,my,sx,sy,howdead);
- return retval;
- }
- lscreen[nyr][x] = '<';
- draw_object(y,x+1,' ');
- draw_object(nyr,x,'<');
- if(audio_flag) play_audio_sample(MOVING_ARROW_SND);
- refresh_screen();
- delay(pause1);
- retval += fall(mx,my,x-1,nyr,sx,sy,howdead);
- moving = 0;
- retval += check(mx,my,x+1,y,-1,0,sx,sy,howdead);
- if (lscreen[nyr][x-1] == '@') {
- strcpy(howdead,"a speeding arrow");
- if(audio_flag) play_audio_sample(KILLED_BY_A_SND);
- return(1);
- }
- if (lscreen[nyr][x-1] == 'M') {
- *mx = *my = -2;
- lscreen[nyr][x-1] = ' ';
- if(audio_flag) play_audio_sample(DEAD_M_SND);
- }
- }
- if ((lscreen[nyl][x] != ' ') && (lscreen[nyl][x] != '^') &&
- (lscreen[nyl][x] != 'M') && (lscreen[nyl][x] != 'B'))
- nyl = -1;
- if ((lscreen[y][x-1] == '>') && (nyl >= 0) &&
- (x > 0)) { /* arrow moves ( > ) ? */
- moving = 1;
- lscreen[y][x-1] = ' ';
- if (lscreen[nyl][x] == '@') {
- strcpy(howdead,"a speeding arrow");
- if(audio_flag) play_audio_sample(KILLED_BY_A_SND);
- retval = 1;
- }
- if (lscreen[nyl][x] == 'M') {
- *mx = *my = -2;
- lscreen[nyl][x] = ' ';
- if(audio_flag) play_audio_sample(DEAD_M_SND);
- }
- if (lscreen[nyr][x] == 'B') {
- retval = bang(x,nyr,mx,my,sx,sy,howdead);
- return retval;
- }
- lscreen[nyl][x] = '>';
- draw_object(y,x-1,' ');
- draw_object(nyl,x,'>');
- if(audio_flag) play_audio_sample(MOVING_ARROW_SND);
- refresh_screen();
- delay(pause1);
- retval += fall(mx,my,x+1,nyl,sx,sy,howdead);
- moving = 0;
- retval += check(mx,my,x-1,y,1,0,sx,sy,howdead);
- if (lscreen[nyl][x+1] == '@') {
- strcpy(howdead,"a speeding arrow");
- if(audio_flag) play_audio_sample(KILLED_BY_A_SND);
- return(1);
- }
- if (lscreen[nyl][x+1] == 'M') {
- *mx = *my = -2;
- lscreen[nyl][x+1] = ' ';
- if(audio_flag) play_audio_sample(DEAD_M_SND);
- }
- }
-
- if (lscreen[y][nxu] != ' ')
- nxu = -1;
- if ((lscreen[y+1][x] == '^') && (nxu >= 0) && (y < NOOFROWS) &&
- (lscreen[y][x] != '^')&&(lscreen[y][x] != 'B')) { /* balloon rises? */
- lscreen[y+1][x] = ' ';
- lscreen[y][nxu] = '^';
- draw_object(y+1,x,' ');
- draw_object(y,nxu,'^');
- refresh_screen();
- delay(pause1);
- retval += fall(mx,my,nxu ,y-1,sx,sy,howdead);
- retval += check(mx,my,x,y+1,0,-1,sx,sy,howdead);
- }
-
- nx = x; ny = y;
-
- if (lscreen[y][x] == ' ') { /* thingy moves? */
- if ((y > 1) && (lscreen[y-1][x] == '~') && (lscreen[y-2][x] == 'O'))
- /* boulder pushes */
- ny--;
- else if ((x > 1) && (lscreen[y][x-1] == '~') && (lscreen[y][x-2] == '>'))
- /* arrow pushes */
- nx--;
- else if ((x < (ROWLEN-1)) && (lscreen[y][x+1] == '~') &&
- (lscreen[y][x+2] == '<'))
- /* arrow pushes */
- nx++;
- else if ((y < (NOOFROWS-1)) && (lscreen[y+1][x] == '~') &&
- (lscreen[y+2][x] == '^'))
- /* balloon pushes */
- ny++;
- }
-
- if ((x != nx) || (y != ny)) {
- lscreen[y][x] = '~';
- lscreen[ny][nx] = lscreen[2*ny-y][2*nx-x];
- lscreen[2*ny-y][2*nx-x] = ' ';
- draw_object(ny*2-y,nx*2-x,' ');
- draw_object(ny,nx,lscreen[ny][nx]);
- draw_object(y,x,'~');
- refresh_screen();
- delay(pause1);
- retval += fall(mx,my,2*x-nx,2*y-ny,sx,sy,howdead);
- retval += check(mx,my,2*nx-x,2*ny-y,nx-x,ny-y,sx,sy,howdead);
- }
-
- if (retval > 0)
- return(1);
- return(0);
- }
-
- int bang(x, y, mx, my, sx, sy, howdead)
- /* explosion centre x,y */
- int x, y, sx, sy, *mx, *my;
- char *howdead;
- {
- int retval = 0;
- int ba, bb; /* abbrevs for 'bang index a' and 'bang index b' :-) */
- int gottim = 0;
-
- lscreen[y][x] = ' ';
- /* fill with bangs */
- for (ba = -1; ba < 2; ba++)
- for (bb = -1; bb < 2; bb++) {
- if (lscreen[y+ba][x+bb] == '#') continue; /* rock indestructable */
- if (lscreen[y+ba][x+bb] == '@') gottim = 1;
- if (lscreen[y+ba][x+bb] == 'M') *mx = *my = -2; /* kill monster */
- if (lscreen[y+ba][x+bb] == 'B')
- gottim += bang(x+bb,y+ba,mx,my,sx,sy,howdead);
- lscreen[y+ba][x+bb] = ' ';
-
- if (((x+bb) > -1) && ((y+ba) > -1) &&
- ((x+bb) < ROWLEN) && ((y+ba) < NOOFROWS)) {
- draw_object(y+ba,x+bb,'%');
- }
- }
- refresh_screen();
- if (gottim) {
- strcpy(howdead,"an exploding bomb");
- return 1;
- }
- /* erase it all */
- for (ba = -1; ba < 2; ba++)
- for (bb = -1; bb < 2; bb++) {
- if (lscreen[y+ba][x+bb] == '#') continue;
- if (((x+bb) > -1) && ((y+ba) > -1) &&
- ((x+bb) < ROWLEN) && ((y+ba) < NOOFROWS)) {
- draw_object(y+ba,x+bb,' ');
- }
- }
- refresh_screen();
-
- /* make all the necessary falling */
- retval = check(mx,my,x-1,y-1,1,0,sx,sy,howdead);
- retval += check(mx,my,x-1,y+1,0,-1,sx,sy,howdead);
- retval += check(mx,my,x+1,y-1,0,1,sx,sy,howdead);
- retval += check(mx,my,x+1,y+1,-1,0,sx,sy,howdead);
- return retval;
- }
-